{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 31-helix"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Schniepp Lab, 2018–2021\n",
    "\n",
    "Coordinates (10.1016/s0926-6585(96)90019-9)  \n",
    "Spherical: https://en.wikipedia.org/wiki/Spherical_coordinate_system, ISO convention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from mpl_toolkits.mplot3d import axes3d, Axes3D\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "%matplotlib notebook\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "# Several classes and helper functions, see individual files for comments\n",
    "from Vector import Vector\n",
    "from Helpers import degree_to_radian, radian_to_degree, rotate_by_degree\n",
    "from Atom import Atom\n",
    "from Amino import Amino"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set up the coordinates for each atom, according to DOI: 10.1016/s0926-6585(96)90019-9\n",
    "\n",
    "C1 = Atom('C', r_xy = 1.27, phi = degree_to_radian(71), z = 0.0)\n",
    "C1_p = Atom('C', r_xy = 0.26, phi = degree_to_radian(88.2), z = 1.14)\n",
    "O1 = Atom('O', r_xy = 1.17, phi = degree_to_radian(186.4), z = 1.26)\n",
    "N1 = Atom('N', r_xy = 1.00, phi = degree_to_radian(356.2), z = 1.94)\n",
    "H1 = Atom('H', r_xy = 1.95, phi = degree_to_radian(7.9), z = 1.82)\n",
    "\n",
    "N0 = N1.duplicate_atom_to_location(-3.10, -240)\n",
    "H0 = H1.duplicate_atom_to_location(-3.10, -240)\n",
    "\n",
    "C2 = Atom('C', r_xy = 1.27, phi = degree_to_radian(311.0), z = 3.10)\n",
    "C2_p = C1_p.duplicate_atom_to_location(3.10, 240)\n",
    "O2 = O1.duplicate_atom_to_location(3.10, 240)\n",
    "N2 = N1.duplicate_atom_to_location(3.10, 240)\n",
    "H2 = H1.duplicate_atom_to_location(3.10, 240)\n",
    "H2_p = Atom('H', r_xy = 2.17, phi = degree_to_radian(322.8), z = 3.38)\n",
    "H2_pp = Atom('H', r_xy = 1.72, phi = degree_to_radian(277.1), z = 2.86)\n",
    "\n",
    "H1_p = H2_p.duplicate_atom_to_location(-3.10, -240)\n",
    "H1_pp = H2_pp.duplicate_atom_to_location(-3.10, -240)\n",
    "\n",
    "C3 = C2.duplicate_atom_to_location(3.10, 240)\n",
    "C3_p = C2_p.duplicate_atom_to_location(3.10, 240)\n",
    "O3 = O2.duplicate_atom_to_location(3.10, 240)\n",
    "N3 = N2.duplicate_atom_to_location(3.10, 240)\n",
    "H3 = H2.duplicate_atom_to_location(3.10, 240)\n",
    "H3_p = H2_p.duplicate_atom_to_location(3.10, 240)\n",
    "H3_pp = H2_pp.duplicate_atom_to_location(3.10, 240)\n",
    "\n",
    "gly_2_h = [H1_p, H1_pp, C1, C1_p, O1, N1, H1, H2_p, H2_pp, C2, C2_p, O2, N2, H2, H3_p, H3_pp, C3, C3_p, O3, N3, H3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1.27, 71.0, 0.0)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C1.get_cylindrical(mode = 'degree')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Amino.Amino at 0x105562ad0>,\n",
       " <Amino.Amino at 0x105562e10>,\n",
       " <Amino.Amino at 0x105562fd0>]"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Set up the 31-helix structure\n",
    "\n",
    "coord0 = []\n",
    "coord0.append(list(N0.get_Cartesian()))\n",
    "coord0.append(list(C1.get_Cartesian()))\n",
    "coord0.append(list(C1_p.get_Cartesian()))\n",
    "coord0.append(list(O1.get_Cartesian()))\n",
    "coord0.append(list(H1_p.get_Cartesian()))\n",
    "coord0.append(list(H0.get_Cartesian()))\n",
    "coord0.append(list(H1_pp.get_Cartesian()))\n",
    "amino0 = Amino('GLY', 0, coord0)\n",
    "\n",
    "coord1 = []\n",
    "coord1.append(list(N1.get_Cartesian()))\n",
    "coord1.append(list(C2.get_Cartesian()))\n",
    "coord1.append(list(C2_p.get_Cartesian()))\n",
    "coord1.append(list(O2.get_Cartesian()))\n",
    "coord1.append(list(H2_p.get_Cartesian()))\n",
    "coord1.append(list(H1.get_Cartesian()))\n",
    "coord1.append(list(H2_pp.get_Cartesian()))\n",
    "amino1 = Amino('GLY', 1, coord1, prev = amino0)\n",
    "\n",
    "coord2 = []\n",
    "coord2.append(list(N2.get_Cartesian()))\n",
    "coord2.append(list(C3.get_Cartesian()))\n",
    "coord2.append(list(C3_p.get_Cartesian()))\n",
    "coord2.append(list(O3.get_Cartesian()))\n",
    "coord2.append(list(H3_p.get_Cartesian()))\n",
    "coord2.append(list(H2.get_Cartesian()))\n",
    "coord2.append(list(H3_pp.get_Cartesian()))\n",
    "amino2 = Amino('GLY', 2, coord2, prev = amino1)\n",
    "\n",
    "gly_31_helix = []\n",
    "gly_31_helix.append(amino0)\n",
    "gly_31_helix.append(amino1)\n",
    "gly_31_helix.append(amino2)\n",
    "\n",
    "gly_31_helix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/javascript": [
       "/* Put everything inside the global mpl namespace */\n",
       "window.mpl = {};\n",
       "\n",
       "\n",
       "mpl.get_websocket_type = function() {\n",
       "    if (typeof(WebSocket) !== 'undefined') {\n",
       "        return WebSocket;\n",
       "    } else if (typeof(MozWebSocket) !== 'undefined') {\n",
       "        return MozWebSocket;\n",
       "    } else {\n",
       "        alert('Your browser does not have WebSocket support.' +\n",
       "              'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
       "              'Firefox 4 and 5 are also supported but you ' +\n",
       "              'have to enable WebSockets in about:config.');\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
       "    this.id = figure_id;\n",
       "\n",
       "    this.ws = websocket;\n",
       "\n",
       "    this.supports_binary = (this.ws.binaryType != undefined);\n",
       "\n",
       "    if (!this.supports_binary) {\n",
       "        var warnings = document.getElementById(\"mpl-warnings\");\n",
       "        if (warnings) {\n",
       "            warnings.style.display = 'block';\n",
       "            warnings.textContent = (\n",
       "                \"This browser does not support binary websocket messages. \" +\n",
       "                    \"Performance may be slow.\");\n",
       "        }\n",
       "    }\n",
       "\n",
       "    this.imageObj = new Image();\n",
       "\n",
       "    this.context = undefined;\n",
       "    this.message = undefined;\n",
       "    this.canvas = undefined;\n",
       "    this.rubberband_canvas = undefined;\n",
       "    this.rubberband_context = undefined;\n",
       "    this.format_dropdown = undefined;\n",
       "\n",
       "    this.image_mode = 'full';\n",
       "\n",
       "    this.root = $('<div/>');\n",
       "    this._root_extra_style(this.root)\n",
       "    this.root.attr('style', 'display: inline-block');\n",
       "\n",
       "    $(parent_element).append(this.root);\n",
       "\n",
       "    this._init_header(this);\n",
       "    this._init_canvas(this);\n",
       "    this._init_toolbar(this);\n",
       "\n",
       "    var fig = this;\n",
       "\n",
       "    this.waiting = false;\n",
       "\n",
       "    this.ws.onopen =  function () {\n",
       "            fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
       "            fig.send_message(\"send_image_mode\", {});\n",
       "            if (mpl.ratio != 1) {\n",
       "                fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
       "            }\n",
       "            fig.send_message(\"refresh\", {});\n",
       "        }\n",
       "\n",
       "    this.imageObj.onload = function() {\n",
       "            if (fig.image_mode == 'full') {\n",
       "                // Full images could contain transparency (where diff images\n",
       "                // almost always do), so we need to clear the canvas so that\n",
       "                // there is no ghosting.\n",
       "                fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
       "            }\n",
       "            fig.context.drawImage(fig.imageObj, 0, 0);\n",
       "        };\n",
       "\n",
       "    this.imageObj.onunload = function() {\n",
       "        fig.ws.close();\n",
       "    }\n",
       "\n",
       "    this.ws.onmessage = this._make_on_message_function(this);\n",
       "\n",
       "    this.ondownload = ondownload;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_header = function() {\n",
       "    var titlebar = $(\n",
       "        '<div class=\"ui-dialog-titlebar ui-widget-header ui-corner-all ' +\n",
       "        'ui-helper-clearfix\"/>');\n",
       "    var titletext = $(\n",
       "        '<div class=\"ui-dialog-title\" style=\"width: 100%; ' +\n",
       "        'text-align: center; padding: 3px;\"/>');\n",
       "    titlebar.append(titletext)\n",
       "    this.root.append(titlebar);\n",
       "    this.header = titletext[0];\n",
       "}\n",
       "\n",
       "\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_canvas = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var canvas_div = $('<div/>');\n",
       "\n",
       "    canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
       "\n",
       "    function canvas_keyboard_event(event) {\n",
       "        return fig.key_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    canvas_div.keydown('key_press', canvas_keyboard_event);\n",
       "    canvas_div.keyup('key_release', canvas_keyboard_event);\n",
       "    this.canvas_div = canvas_div\n",
       "    this._canvas_extra_style(canvas_div)\n",
       "    this.root.append(canvas_div);\n",
       "\n",
       "    var canvas = $('<canvas/>');\n",
       "    canvas.addClass('mpl-canvas');\n",
       "    canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
       "\n",
       "    this.canvas = canvas[0];\n",
       "    this.context = canvas[0].getContext(\"2d\");\n",
       "\n",
       "    var backingStore = this.context.backingStorePixelRatio ||\n",
       "\tthis.context.webkitBackingStorePixelRatio ||\n",
       "\tthis.context.mozBackingStorePixelRatio ||\n",
       "\tthis.context.msBackingStorePixelRatio ||\n",
       "\tthis.context.oBackingStorePixelRatio ||\n",
       "\tthis.context.backingStorePixelRatio || 1;\n",
       "\n",
       "    mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
       "\n",
       "    var rubberband = $('<canvas/>');\n",
       "    rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
       "\n",
       "    var pass_mouse_events = true;\n",
       "\n",
       "    canvas_div.resizable({\n",
       "        start: function(event, ui) {\n",
       "            pass_mouse_events = false;\n",
       "        },\n",
       "        resize: function(event, ui) {\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "        stop: function(event, ui) {\n",
       "            pass_mouse_events = true;\n",
       "            fig.request_resize(ui.size.width, ui.size.height);\n",
       "        },\n",
       "    });\n",
       "\n",
       "    function mouse_event_fn(event) {\n",
       "        if (pass_mouse_events)\n",
       "            return fig.mouse_event(event, event['data']);\n",
       "    }\n",
       "\n",
       "    rubberband.mousedown('button_press', mouse_event_fn);\n",
       "    rubberband.mouseup('button_release', mouse_event_fn);\n",
       "    // Throttle sequential mouse events to 1 every 20ms.\n",
       "    rubberband.mousemove('motion_notify', mouse_event_fn);\n",
       "\n",
       "    rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
       "    rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
       "\n",
       "    canvas_div.on(\"wheel\", function (event) {\n",
       "        event = event.originalEvent;\n",
       "        event['data'] = 'scroll'\n",
       "        if (event.deltaY < 0) {\n",
       "            event.step = 1;\n",
       "        } else {\n",
       "            event.step = -1;\n",
       "        }\n",
       "        mouse_event_fn(event);\n",
       "    });\n",
       "\n",
       "    canvas_div.append(canvas);\n",
       "    canvas_div.append(rubberband);\n",
       "\n",
       "    this.rubberband = rubberband;\n",
       "    this.rubberband_canvas = rubberband[0];\n",
       "    this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
       "    this.rubberband_context.strokeStyle = \"#000000\";\n",
       "\n",
       "    this._resize_canvas = function(width, height) {\n",
       "        // Keep the size of the canvas, canvas container, and rubber band\n",
       "        // canvas in synch.\n",
       "        canvas_div.css('width', width)\n",
       "        canvas_div.css('height', height)\n",
       "\n",
       "        canvas.attr('width', width * mpl.ratio);\n",
       "        canvas.attr('height', height * mpl.ratio);\n",
       "        canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
       "\n",
       "        rubberband.attr('width', width);\n",
       "        rubberband.attr('height', height);\n",
       "    }\n",
       "\n",
       "    // Set the figure to an initial 600x600px, this will subsequently be updated\n",
       "    // upon first draw.\n",
       "    this._resize_canvas(600, 600);\n",
       "\n",
       "    // Disable right mouse context menu.\n",
       "    $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
       "        return false;\n",
       "    });\n",
       "\n",
       "    function set_focus () {\n",
       "        canvas.focus();\n",
       "        canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    window.setTimeout(set_focus, 100);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items) {\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) {\n",
       "            // put a spacer in here.\n",
       "            continue;\n",
       "        }\n",
       "        var button = $('<button/>');\n",
       "        button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
       "                        'ui-button-icon-only');\n",
       "        button.attr('role', 'button');\n",
       "        button.attr('aria-disabled', 'false');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "\n",
       "        var icon_img = $('<span/>');\n",
       "        icon_img.addClass('ui-button-icon-primary ui-icon');\n",
       "        icon_img.addClass(image);\n",
       "        icon_img.addClass('ui-corner-all');\n",
       "\n",
       "        var tooltip_span = $('<span/>');\n",
       "        tooltip_span.addClass('ui-button-text');\n",
       "        tooltip_span.html(tooltip);\n",
       "\n",
       "        button.append(icon_img);\n",
       "        button.append(tooltip_span);\n",
       "\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    var fmt_picker_span = $('<span/>');\n",
       "\n",
       "    var fmt_picker = $('<select/>');\n",
       "    fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
       "    fmt_picker_span.append(fmt_picker);\n",
       "    nav_element.append(fmt_picker_span);\n",
       "    this.format_dropdown = fmt_picker[0];\n",
       "\n",
       "    for (var ind in mpl.extensions) {\n",
       "        var fmt = mpl.extensions[ind];\n",
       "        var option = $(\n",
       "            '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);\n",
       "        fmt_picker.append(option)\n",
       "    }\n",
       "\n",
       "    // Add hover states to the ui-buttons\n",
       "    $( \".ui-button\" ).hover(\n",
       "        function() { $(this).addClass(\"ui-state-hover\");},\n",
       "        function() { $(this).removeClass(\"ui-state-hover\");}\n",
       "    );\n",
       "\n",
       "    var status_bar = $('<span class=\"mpl-message\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
       "    // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
       "    // which will in turn request a refresh of the image.\n",
       "    this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_message = function(type, properties) {\n",
       "    properties['type'] = type;\n",
       "    properties['figure_id'] = this.id;\n",
       "    this.ws.send(JSON.stringify(properties));\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.send_draw_message = function() {\n",
       "    if (!this.waiting) {\n",
       "        this.waiting = true;\n",
       "        this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
       "    }\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    var format_dropdown = fig.format_dropdown;\n",
       "    var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
       "    fig.ondownload(fig, format);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
       "    var size = msg['size'];\n",
       "    if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
       "        fig._resize_canvas(size[0], size[1]);\n",
       "        fig.send_message(\"refresh\", {});\n",
       "    };\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
       "    var x0 = msg['x0'] / mpl.ratio;\n",
       "    var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
       "    var x1 = msg['x1'] / mpl.ratio;\n",
       "    var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
       "    x0 = Math.floor(x0) + 0.5;\n",
       "    y0 = Math.floor(y0) + 0.5;\n",
       "    x1 = Math.floor(x1) + 0.5;\n",
       "    y1 = Math.floor(y1) + 0.5;\n",
       "    var min_x = Math.min(x0, x1);\n",
       "    var min_y = Math.min(y0, y1);\n",
       "    var width = Math.abs(x1 - x0);\n",
       "    var height = Math.abs(y1 - y0);\n",
       "\n",
       "    fig.rubberband_context.clearRect(\n",
       "        0, 0, fig.canvas.width, fig.canvas.height);\n",
       "\n",
       "    fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
       "    // Updates the figure title.\n",
       "    fig.header.textContent = msg['label'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
       "    var cursor = msg['cursor'];\n",
       "    switch(cursor)\n",
       "    {\n",
       "    case 0:\n",
       "        cursor = 'pointer';\n",
       "        break;\n",
       "    case 1:\n",
       "        cursor = 'default';\n",
       "        break;\n",
       "    case 2:\n",
       "        cursor = 'crosshair';\n",
       "        break;\n",
       "    case 3:\n",
       "        cursor = 'move';\n",
       "        break;\n",
       "    }\n",
       "    fig.rubberband_canvas.style.cursor = cursor;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_message = function(fig, msg) {\n",
       "    fig.message.textContent = msg['message'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
       "    // Request the server to send over a new figure.\n",
       "    fig.send_draw_message();\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
       "    fig.image_mode = msg['mode'];\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Called whenever the canvas gets updated.\n",
       "    this.send_message(\"ack\", {});\n",
       "}\n",
       "\n",
       "// A function to construct a web socket function for onmessage handling.\n",
       "// Called in the figure constructor.\n",
       "mpl.figure.prototype._make_on_message_function = function(fig) {\n",
       "    return function socket_on_message(evt) {\n",
       "        if (evt.data instanceof Blob) {\n",
       "            /* FIXME: We get \"Resource interpreted as Image but\n",
       "             * transferred with MIME type text/plain:\" errors on\n",
       "             * Chrome.  But how to set the MIME type?  It doesn't seem\n",
       "             * to be part of the websocket stream */\n",
       "            evt.data.type = \"image/png\";\n",
       "\n",
       "            /* Free the memory for the previous frames */\n",
       "            if (fig.imageObj.src) {\n",
       "                (window.URL || window.webkitURL).revokeObjectURL(\n",
       "                    fig.imageObj.src);\n",
       "            }\n",
       "\n",
       "            fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
       "                evt.data);\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "        else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
       "            fig.imageObj.src = evt.data;\n",
       "            fig.updated_canvas_event();\n",
       "            fig.waiting = false;\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        var msg = JSON.parse(evt.data);\n",
       "        var msg_type = msg['type'];\n",
       "\n",
       "        // Call the  \"handle_{type}\" callback, which takes\n",
       "        // the figure and JSON message as its only arguments.\n",
       "        try {\n",
       "            var callback = fig[\"handle_\" + msg_type];\n",
       "        } catch (e) {\n",
       "            console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
       "            return;\n",
       "        }\n",
       "\n",
       "        if (callback) {\n",
       "            try {\n",
       "                // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
       "                callback(fig, msg);\n",
       "            } catch (e) {\n",
       "                console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
       "            }\n",
       "        }\n",
       "    };\n",
       "}\n",
       "\n",
       "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
       "mpl.findpos = function(e) {\n",
       "    //this section is from http://www.quirksmode.org/js/events_properties.html\n",
       "    var targ;\n",
       "    if (!e)\n",
       "        e = window.event;\n",
       "    if (e.target)\n",
       "        targ = e.target;\n",
       "    else if (e.srcElement)\n",
       "        targ = e.srcElement;\n",
       "    if (targ.nodeType == 3) // defeat Safari bug\n",
       "        targ = targ.parentNode;\n",
       "\n",
       "    // jQuery normalizes the pageX and pageY\n",
       "    // pageX,Y are the mouse positions relative to the document\n",
       "    // offset() returns the position of the element relative to the document\n",
       "    var x = e.pageX - $(targ).offset().left;\n",
       "    var y = e.pageY - $(targ).offset().top;\n",
       "\n",
       "    return {\"x\": x, \"y\": y};\n",
       "};\n",
       "\n",
       "/*\n",
       " * return a copy of an object with only non-object keys\n",
       " * we need this to avoid circular references\n",
       " * http://stackoverflow.com/a/24161582/3208463\n",
       " */\n",
       "function simpleKeys (original) {\n",
       "  return Object.keys(original).reduce(function (obj, key) {\n",
       "    if (typeof original[key] !== 'object')\n",
       "        obj[key] = original[key]\n",
       "    return obj;\n",
       "  }, {});\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.mouse_event = function(event, name) {\n",
       "    var canvas_pos = mpl.findpos(event)\n",
       "\n",
       "    if (name === 'button_press')\n",
       "    {\n",
       "        this.canvas.focus();\n",
       "        this.canvas_div.focus();\n",
       "    }\n",
       "\n",
       "    var x = canvas_pos.x * mpl.ratio;\n",
       "    var y = canvas_pos.y * mpl.ratio;\n",
       "\n",
       "    this.send_message(name, {x: x, y: y, button: event.button,\n",
       "                             step: event.step,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "\n",
       "    /* This prevents the web browser from automatically changing to\n",
       "     * the text insertion cursor when the button is pressed.  We want\n",
       "     * to control all of the cursor setting manually through the\n",
       "     * 'cursor' event from matplotlib */\n",
       "    event.preventDefault();\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    // Handle any extra behaviour associated with a key event\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.key_event = function(event, name) {\n",
       "\n",
       "    // Prevent repeat events\n",
       "    if (name == 'key_press')\n",
       "    {\n",
       "        if (event.which === this._key)\n",
       "            return;\n",
       "        else\n",
       "            this._key = event.which;\n",
       "    }\n",
       "    if (name == 'key_release')\n",
       "        this._key = null;\n",
       "\n",
       "    var value = '';\n",
       "    if (event.ctrlKey && event.which != 17)\n",
       "        value += \"ctrl+\";\n",
       "    if (event.altKey && event.which != 18)\n",
       "        value += \"alt+\";\n",
       "    if (event.shiftKey && event.which != 16)\n",
       "        value += \"shift+\";\n",
       "\n",
       "    value += 'k';\n",
       "    value += event.which.toString();\n",
       "\n",
       "    this._key_event_extra(event, name);\n",
       "\n",
       "    this.send_message(name, {key: value,\n",
       "                             guiEvent: simpleKeys(event)});\n",
       "    return false;\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
       "    if (name == 'download') {\n",
       "        this.handle_save(this, null);\n",
       "    } else {\n",
       "        this.send_message(\"toolbar_button\", {name: name});\n",
       "    }\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
       "    this.message.textContent = tooltip;\n",
       "};\n",
       "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to  previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
       "\n",
       "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
       "\n",
       "mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
       "    // Create a \"websocket\"-like object which calls the given IPython comm\n",
       "    // object with the appropriate methods. Currently this is a non binary\n",
       "    // socket, so there is still some room for performance tuning.\n",
       "    var ws = {};\n",
       "\n",
       "    ws.close = function() {\n",
       "        comm.close()\n",
       "    };\n",
       "    ws.send = function(m) {\n",
       "        //console.log('sending', m);\n",
       "        comm.send(m);\n",
       "    };\n",
       "    // Register the callback with on_msg.\n",
       "    comm.on_msg(function(msg) {\n",
       "        //console.log('receiving', msg['content']['data'], msg);\n",
       "        // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
       "        ws.onmessage(msg['content']['data'])\n",
       "    });\n",
       "    return ws;\n",
       "}\n",
       "\n",
       "mpl.mpl_figure_comm = function(comm, msg) {\n",
       "    // This is the function which gets called when the mpl process\n",
       "    // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
       "\n",
       "    var id = msg.content.data.id;\n",
       "    // Get hold of the div created by the display call when the Comm\n",
       "    // socket was opened in Python.\n",
       "    var element = $(\"#\" + id);\n",
       "    var ws_proxy = comm_websocket_adapter(comm)\n",
       "\n",
       "    function ondownload(figure, format) {\n",
       "        window.open(figure.imageObj.src);\n",
       "    }\n",
       "\n",
       "    var fig = new mpl.figure(id, ws_proxy,\n",
       "                           ondownload,\n",
       "                           element.get(0));\n",
       "\n",
       "    // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
       "    // web socket which is closed, not our websocket->open comm proxy.\n",
       "    ws_proxy.onopen();\n",
       "\n",
       "    fig.parent_element = element.get(0);\n",
       "    fig.cell_info = mpl.find_output_cell(\"<div id='\" + id + \"'></div>\");\n",
       "    if (!fig.cell_info) {\n",
       "        console.error(\"Failed to find cell for figure\", id, fig);\n",
       "        return;\n",
       "    }\n",
       "\n",
       "    var output_index = fig.cell_info[2]\n",
       "    var cell = fig.cell_info[0];\n",
       "\n",
       "};\n",
       "\n",
       "mpl.figure.prototype.handle_close = function(fig, msg) {\n",
       "    var width = fig.canvas.width/mpl.ratio\n",
       "    fig.root.unbind('remove')\n",
       "\n",
       "    // Update the output cell to use the data from the current canvas.\n",
       "    fig.push_to_output();\n",
       "    var dataURL = fig.canvas.toDataURL();\n",
       "    // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
       "    // the notebook keyboard shortcuts fail.\n",
       "    IPython.keyboard_manager.enable()\n",
       "    $(fig.parent_element).html('<img src=\"' + dataURL + '\" width=\"' + width + '\">');\n",
       "    fig.close_ws(fig, msg);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.close_ws = function(fig, msg){\n",
       "    fig.send_message('closing', msg);\n",
       "    // fig.ws.close()\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
       "    // Turn the data on the canvas into data in the output cell.\n",
       "    var width = this.canvas.width/mpl.ratio\n",
       "    var dataURL = this.canvas.toDataURL();\n",
       "    this.cell_info[1]['text/html'] = '<img src=\"' + dataURL + '\" width=\"' + width + '\">';\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.updated_canvas_event = function() {\n",
       "    // Tell IPython that the notebook contents must change.\n",
       "    IPython.notebook.set_dirty(true);\n",
       "    this.send_message(\"ack\", {});\n",
       "    var fig = this;\n",
       "    // Wait a second, then push the new image to the DOM so\n",
       "    // that it is saved nicely (might be nice to debounce this).\n",
       "    setTimeout(function () { fig.push_to_output() }, 1000);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._init_toolbar = function() {\n",
       "    var fig = this;\n",
       "\n",
       "    var nav_element = $('<div/>')\n",
       "    nav_element.attr('style', 'width: 100%');\n",
       "    this.root.append(nav_element);\n",
       "\n",
       "    // Define a callback function for later on.\n",
       "    function toolbar_event(event) {\n",
       "        return fig.toolbar_button_onclick(event['data']);\n",
       "    }\n",
       "    function toolbar_mouse_event(event) {\n",
       "        return fig.toolbar_button_onmouseover(event['data']);\n",
       "    }\n",
       "\n",
       "    for(var toolbar_ind in mpl.toolbar_items){\n",
       "        var name = mpl.toolbar_items[toolbar_ind][0];\n",
       "        var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
       "        var image = mpl.toolbar_items[toolbar_ind][2];\n",
       "        var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
       "\n",
       "        if (!name) { continue; };\n",
       "\n",
       "        var button = $('<button class=\"btn btn-default\" href=\"#\" title=\"' + name + '\"><i class=\"fa ' + image + ' fa-lg\"></i></button>');\n",
       "        button.click(method_name, toolbar_event);\n",
       "        button.mouseover(tooltip, toolbar_mouse_event);\n",
       "        nav_element.append(button);\n",
       "    }\n",
       "\n",
       "    // Add the status bar.\n",
       "    var status_bar = $('<span class=\"mpl-message\" style=\"text-align:right; float: right;\"/>');\n",
       "    nav_element.append(status_bar);\n",
       "    this.message = status_bar[0];\n",
       "\n",
       "    // Add the close button to the window.\n",
       "    var buttongrp = $('<div class=\"btn-group inline pull-right\"></div>');\n",
       "    var button = $('<button class=\"btn btn-mini btn-primary\" href=\"#\" title=\"Stop Interaction\"><i class=\"fa fa-power-off icon-remove icon-large\"></i></button>');\n",
       "    button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
       "    button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
       "    buttongrp.append(button);\n",
       "    var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
       "    titlebar.prepend(buttongrp);\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._root_extra_style = function(el){\n",
       "    var fig = this\n",
       "    el.on(\"remove\", function(){\n",
       "\tfig.close_ws(fig, {});\n",
       "    });\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._canvas_extra_style = function(el){\n",
       "    // this is important to make the div 'focusable\n",
       "    el.attr('tabindex', 0)\n",
       "    // reach out to IPython and tell the keyboard manager to turn it's self\n",
       "    // off when our div gets focus\n",
       "\n",
       "    // location in version 3\n",
       "    if (IPython.notebook.keyboard_manager) {\n",
       "        IPython.notebook.keyboard_manager.register_events(el);\n",
       "    }\n",
       "    else {\n",
       "        // location in version 2\n",
       "        IPython.keyboard_manager.register_events(el);\n",
       "    }\n",
       "\n",
       "}\n",
       "\n",
       "mpl.figure.prototype._key_event_extra = function(event, name) {\n",
       "    var manager = IPython.notebook.keyboard_manager;\n",
       "    if (!manager)\n",
       "        manager = IPython.keyboard_manager;\n",
       "\n",
       "    // Check for shift+enter\n",
       "    if (event.shiftKey && event.which == 13) {\n",
       "        this.canvas_div.blur();\n",
       "        event.shiftKey = false;\n",
       "        // Send a \"J\" for go to next cell\n",
       "        event.which = 74;\n",
       "        event.keyCode = 74;\n",
       "        manager.command_mode();\n",
       "        manager.handle_keydown(event);\n",
       "    }\n",
       "}\n",
       "\n",
       "mpl.figure.prototype.handle_save = function(fig, msg) {\n",
       "    fig.ondownload(fig, null);\n",
       "}\n",
       "\n",
       "\n",
       "mpl.find_output_cell = function(html_output) {\n",
       "    // Return the cell and output element which can be found *uniquely* in the notebook.\n",
       "    // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
       "    // IPython event is triggered only after the cells have been serialised, which for\n",
       "    // our purposes (turning an active figure into a static one), is too late.\n",
       "    var cells = IPython.notebook.get_cells();\n",
       "    var ncells = cells.length;\n",
       "    for (var i=0; i<ncells; i++) {\n",
       "        var cell = cells[i];\n",
       "        if (cell.cell_type === 'code'){\n",
       "            for (var j=0; j<cell.output_area.outputs.length; j++) {\n",
       "                var data = cell.output_area.outputs[j];\n",
       "                if (data.data) {\n",
       "                    // IPython >= 3 moved mimebundle to data attribute of output\n",
       "                    data = data.data;\n",
       "                }\n",
       "                if (data['text/html'] == html_output) {\n",
       "                    return [cell, data, j];\n",
       "                }\n",
       "            }\n",
       "        }\n",
       "    }\n",
       "}\n",
       "\n",
       "// Register the function which deals with the matplotlib target/channel.\n",
       "// The kernel may be null if the page has been refreshed.\n",
       "if (IPython.notebook.kernel != null) {\n",
       "    IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
       "}\n"
      ],
      "text/plain": [
       "<IPython.core.display.Javascript object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<img src=\"data:image/png;base64,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9uXyyy+v+fpQAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEUAAc9YgFAcCEIAABCAAAQhkTQABzJow+UMAAhCAAAQgAIGcEfj/k1McO3+237oAAAAASUVORK5CYII=\" width=\"640\">"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot atoms\n",
    "%matplotlib notebook\n",
    "fig = plt.figure()\n",
    "ax = fig.add_subplot(111, projection = '3d')\n",
    "colors = {'C': 'k', 'H': 'b', 'N': 'g', 'O': 'r', 'R': 'b'}\n",
    "sizes = {'C': 30, 'H': 10, 'N': 30, 'O': 30, 'R': 10}\n",
    "x = []\n",
    "y = []\n",
    "z = []\n",
    "for amino in gly_31_helix:\n",
    "    ax.scatter(amino.N.x, amino.N.y, amino.N.z, c = colors[amino.N.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.N.a_type])\n",
    "    ax.scatter(amino.CA.x, amino.CA.y, amino.CA.z, c = colors[amino.CA.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.CA.a_type])\n",
    "    ax.scatter(amino.C.x, amino.C.y, amino.C.z, c = colors[amino.C.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.C.a_type])\n",
    "    ax.scatter(amino.O.x, amino.O.y, amino.O.z, c = colors[amino.O.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.O.a_type])\n",
    "    ax.scatter(amino.R.x, amino.R.y, amino.R.z, c = colors[amino.R.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.R.a_type])\n",
    "    ax.scatter(amino.H.x, amino.H.y, amino.H.z, c = colors[amino.H.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.H.a_type])\n",
    "    ax.scatter(amino.HA.x, amino.HA.y, amino.HA.z, c = colors[amino.HA.a_type], marker = 'o', \\\n",
    "               s = sizes[amino.HA.a_type])\n",
    "    \n",
    "    x.append(amino.N.x)\n",
    "    x.append(amino.CA.x)\n",
    "    x.append(amino.C.x)\n",
    "    x.append(amino.O.x)\n",
    "    x.append(amino.H.x)\n",
    "    x.append(amino.HA.x)\n",
    "    \n",
    "    y.append(amino.N.y)\n",
    "    y.append(amino.CA.y)\n",
    "    y.append(amino.C.y)\n",
    "    y.append(amino.O.y)\n",
    "    y.append(amino.H.y)\n",
    "    y.append(amino.HA.y)\n",
    "    \n",
    "    z.append(amino.N.z)\n",
    "    z.append(amino.CA.z)\n",
    "    z.append(amino.C.z)\n",
    "    z.append(amino.O.z)\n",
    "    z.append(amino.H.z)\n",
    "    z.append(amino.HA.z)\n",
    "\n",
    "# The helix axis is the z axis\n",
    "ax.plot([0, 0], [0, 0], [-2, 9], '--')\n",
    "\n",
    "# Plot each atom\n",
    "ax.set_xlabel('x')\n",
    "ax.set_ylabel('y')\n",
    "ax.set_zlabel('z')\n",
    "ax.set_xlim(-4, 4)\n",
    "ax.set_ylim(-4, 4)\n",
    "elev = 0\n",
    "azim = -32\n",
    "ax.view_init(elev, azim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# z axis as the helix axis\n",
    "h_axis = Vector(p1 = (0, 0, 0), p2 = (0, 0, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**CO s:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-0.9628884019459919\n",
      "-0.9628884019459922\n",
      "-0.9628884019459913\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "-0.9628884019459919"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(gly_31_helix[0].get_CO_P(h_axis))\n",
    "print(gly_31_helix[1].get_CO_P(h_axis))\n",
    "print(gly_31_helix[2].get_CO_P(h_axis))\n",
    "P_CO = np.mean([gly_31_helix[0].get_CO_P(h_axis), gly_31_helix[1].get_CO_P(h_axis), gly_31_helix[2].get_CO_P(h_axis)])\n",
    "P_CO"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**CA(lpha)Cs:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.42467422697161367\n",
      "0.42467422697161417\n",
      "0.424674226971614\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.42467422697161394"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(gly_31_helix[0].get_CAC_P(h_axis))\n",
    "print(gly_31_helix[1].get_CAC_P(h_axis))\n",
    "print(gly_31_helix[2].get_CAC_P(h_axis))\n",
    "\n",
    "P_CAC = np.mean([gly_31_helix[0].get_CAC_P(h_axis), gly_31_helix[1].get_CAC_P(h_axis), gly_31_helix[2].get_CAC_P(h_axis)])\n",
    "P_CAC"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**CN s:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.08211030219794017\n",
      "0.08211030219794035\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.08211030219794027"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(gly_31_helix[1].get_CN_P(h_axis))\n",
    "print(gly_31_helix[2].get_CN_P(h_axis))\n",
    "P_CN = np.mean([gly_31_helix[1].get_CN_P(h_axis), gly_31_helix[2].get_CN_P(h_axis)])\n",
    "P_CN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**NHib:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.5779163686166215\n",
      "0.5779163686166218\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.5779163686166217"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(gly_31_helix[1].get_NHib_P(h_axis))\n",
    "print(gly_31_helix[2].get_NHib_P(h_axis))\n",
    "P_NHib = np.mean([gly_31_helix[1].get_NHib_P(h_axis), gly_31_helix[2].get_NHib_P(h_axis)])\n",
    "P_NHib"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**CH2 tw and w:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.894211783381338\n",
      "0.8942117833813382\n",
      "0.8942117833813376\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "0.8942117833813379"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(gly_31_helix[0].get_CAHAR_P(h_axis))\n",
    "print(gly_31_helix[1].get_CAHAR_P(h_axis))\n",
    "print(gly_31_helix[2].get_CAHAR_P(h_axis))\n",
    "P_CH2 = np.mean([gly_31_helix[0].get_CAHAR_P(h_axis), gly_31_helix[1].get_CAHAR_P(h_axis),\n",
    "               gly_31_helix[2].get_CAHAR_P(h_axis)])\n",
    "P_CH2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "average of CO P values =  -0.9628884019459919\n",
      "average of CAC P values =  0.42467422697161394\n",
      "average of CN P values =  0.08211030219794027\n",
      "average of NHib P values =  0.5779163686166217\n",
      "average of CH2 P values =  0.8942117833813379\n",
      "Amide I (78% COs and 22% CNs):  -0.7329886870343268\n",
      "Amide II (60% NHib, 25% CNs, and 15% CACs):  0.43097853076520015\n",
      "Amide III (P_CH2):  0.8942117833813379\n"
     ]
    }
   ],
   "source": [
    "# Results:\n",
    "\n",
    "print('average of CO P values = ', P_CO)\n",
    "print('average of CAC P values = ', P_CAC)\n",
    "print('average of CN P values = ', P_CN)\n",
    "print('average of NHib P values = ', P_NHib)\n",
    "print('average of CH2 P values = ', P_CH2)\n",
    "print('Amide I (78% COs and 22% CNs): ', P_CO * 0.78 + P_CN *0.22)\n",
    "print('Amide II (60% NHib, 25% CNs, and 15% CACs): ', P_NHib * 0.6 + P_CN * 0.25 + P_CAC * 0.15)\n",
    "print('Amide III (P_CH2): ', P_CH2)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
